package com.jingzhongbao.concurrent.lock;
/**
 * User:jzb
 * Date:2018/11/15
 * Time:13:02
 * 生产者
 * 分两步：先生产，然后放入蓝子
 */
public class Provider implements Runnable {
	/**
	 * 蓝子
	 */
	private final Bucket bucket;

	/**
	 * 当前手上拿着的东西
	 */
	private ThreadLocal<String> currentHold = new ThreadLocal<>();
	/**
	 * 记录总共生产出来东西的数量
	 */
	private ThreadLocal<Integer> count = new ThreadLocal<>();

	public Provider(Bucket bucket) {
		this.bucket = bucket;
	}

	@Override
	public void run() {
		// 初始化本地线程执有的变量，不能写在Construct中，否则无效
		currentHold.set(null);
		count.set(0);

		while (true) {
			String obj = currentHold.get();
			if (obj == null) {// 如果生产者手上没有拿着东西，则生产，否则先要放入篮子中
				obj = Produce.produce();
				count.set(count.get() + 1);
				System.out.println(Thread.currentThread().getName() + ":生产了第["
						+ count.get() + "]个" + obj);
			}
			bucket.getLock().lock();
			boolean result = bucket.add(Thread.currentThread().getName()
					+ "生产的第[" + count.get() + "]个" + obj);
			if (result) {
				currentHold.remove();
				System.out.println(Thread.currentThread().getName() + ":放入了第["
						+ count.get() + "]个" + obj);
				System.out.println("篮子大小为:" + bucket.size());
				bucket.getLock().unlock();
			} else {
				currentHold.set(obj);
				System.out.println(Thread.currentThread().getName() + ":篮子满了");
				bucket.getFetchLock().signalAll();// 通知消费者去消费
				try {
					bucket.getAddLock().await();// 停止生产
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					bucket.getLock().unlock();
				}
			}
		}
	}
}
